package com.it2.pdfdemo.util;


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

@Slf4j
public class DrawPicFromUrlToOSS {
    public static void main(String[] args) throws UnsupportedEncodingException {
        DrawPicFromUrlToOSS d = new DrawPicFromUrlToOSS();
        FontText text = new FontText();
        text.setText("你好，欢迎访问中秋图片！");
        text.setText2("中秋节快乐！");
        text.setText_color("#FF4040");
        text.setText_size(50);
        BufferedImage bimage = d.drawTextInRemoteImg("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fbpic.588ku.com%2Felement_origin_min_pic%2F16%2F07%2F06%2F17577cd55945262.jpg%21r650&refer=http%3A%2F%2Fbpic.588ku.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628933927&t=25af9b7a5f461f17c14ade7651ba0daa", text);
        d.writeFileToPath(bimage, "D:\\test2\\123.jpg");
        System.out.println("执行结束");
    }

    //bimage写到指定路径磁盘上
    public void writeFileToPath(BufferedImage bimage, String outPath) {
        try {
            FileOutputStream out = new FileOutputStream(outPath);
            ImageIO.write(bimage, "JPEG", out);
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 在远程图片上写字
     *
     * @param filePath 远程地址路径
     * @param text     字体格式
     */
    public BufferedImage drawTextInRemoteImg(String filePath, FontText text) throws UnsupportedEncodingException {
        //这一步可以不需要，自定义实现，可以返回null。
//        Font fontSelf = getFont(text);
        Font fontSelf = null;
        //获取远程图片，给定一个url获取到图片后再处理
        BufferedImage img = getBufferedImageDestUrl(filePath);
        //图片宽度
        int imgWidth = img.getWidth(null);
        //图片高度
        int height = img.getHeight(null);
        //创建BufferedImage对象
        BufferedImage bimage = new BufferedImage(imgWidth, height,
                BufferedImage.TYPE_INT_RGB);
        //java.awt组件创建图形
        Graphics2D g = bimage.createGraphics();
        //设置图形
        g.setColor(getColor(text.getText_color()));
        g.setBackground(Color.white);
        g.drawImage(img, 0, 0, null);
        //字体
        Font font;
        if (null != fontSelf) {
            font = fontSelf;
        } else if (!StringUtils.isEmpty(text.getText_font())
                && text.getText_size() != null) {
            font = new Font(text.getText_font(), Font.BOLD,
                    text.getText_size());
        } else {
            font = new Font(null, Font.BOLD, 15);
        }
        //给图形设置字体
        g.setFont(font);
        // 计算文字长度，计算居中的x点坐标
        Graphics2D g2d = img.createGraphics();
        FontMetrics fm = g2d.getFontMetrics(font);
        //设置文本宽高
        setFontContent(g, fm, text, imgWidth);
        g.dispose();
        return bimage;
    }

    //加载字体对象
    public Font getFont(FontText text) {
        Font font = loadFont(text.getText_font(), text.getText_size(), Font.PLAIN);
        return font;
    }

    //设置文本宽高
    public void setFontContent(Graphics2D g, FontMetrics fm, FontText text, int imgWidth) throws UnsupportedEncodingException {
        String userName = new String(text.getText().getBytes("UTF-8"), "UTF-8");
        String userCode = new String(text.getText2().getBytes("UTF-8"), "UTF-8");
        log.info("### drawString-textStr:{}", userName);
        g.drawString(userName, 65, 180);
        int text2Width = (imgWidth - fm.stringWidth(text.getText2())) / 2;
        g.drawString(userCode, text2Width, 420);
    }

    /**
     * 远程图片转BufferedImage
     *
     * @param destUrl 远程图片地址
     * @return
     */
    public static BufferedImage getBufferedImageDestUrl(String destUrl) {
        HttpURLConnection conn = null;
        BufferedImage image = null;
        try {
            URL url = new URL(destUrl);
            conn = (HttpURLConnection) url.openConnection();
            if (conn.getResponseCode() == 200) {
                image = ImageIO.read(conn.getInputStream());
                return image;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }
        return image;
    }

    /**
     * 加载字体，linux服务器上如果没有安装字体库，防止中文乱码，通过以下方法加载字体为InputStream，
     * 再通过Font.createFont(Font.TRUETYPE_FONT, resourceAsStream);生成字体对象Font，这样即使服务器没有安装
     * 字体库，也不会造成中文写到图片上乱码。
     * 如果springboot项目，字体文件*.fft文件要放到resources目录下。并且注意pom文件中的resource和plugin配置
     *
     * @param fontFileName 字体文件
     * @param fontSize     字体大小
     * @return 字体
     */
    public static Font loadFont(String fontFileName, int fontSize, int fontStyle) {
        //第一个参数是外部字体名，第二个是字体大小
        try {
            log.info("### fontFileName :{}", fontFileName);
            InputStream resourceAsStream = VerifyCodeUtils.class
                    .getClassLoader()
                    .getResourceAsStream(fontFileName);
            log.info("### resourceAsStream :{}", resourceAsStream);
            Font dynamicFont = Font.createFont(Font.TRUETYPE_FONT, resourceAsStream);
            Font dynamicFontPt = dynamicFont.deriveFont(fontStyle, fontSize);
            log.info("### fontSize :{}", fontSize);
            resourceAsStream.close();
            return dynamicFontPt;
        } catch (Exception e) {
            log.error("### loadFont-exception:", e);
            //异常处理
            return new Font("宋体", Font.ITALIC, (int) fontSize);
        }
    }

    // 创建color对象
    public static Color getColor(String color) {
        if (color.charAt(0) == '#') {
            color = color.substring(1);
        }
        if (color.length() != 6) {
            return null;
        }
        try {
            int r = Integer.parseInt(color.substring(0, 2), 16);
            int g = Integer.parseInt(color.substring(2, 4), 16);
            int b = Integer.parseInt(color.substring(4), 16);
            return new Color(r, g, b);
        } catch (NumberFormatException nfe) {
            return null;
        }
    }
}

